#pragma once

#include "viml/ast.h"
#include <sstream>
#include <unordered_map>
#include <optional>
#include <set>
#include <memory>

namespace viml {

// 源码位置信息
struct SourcePosition {
    int start_line = 0;
    int start_col = 0;
    int end_line = 0;
    int end_col = 0;
    std::string source_snippet;
    
    SourcePosition() = default;
    SourcePosition(int sl, int sc, int el, int ec, const std::string& snippet = "")
        : start_line(sl), start_col(sc), end_line(el), end_col(ec), source_snippet(snippet) {}
};

// 分析结果标志位
enum class AnalysisFlag {
    IS_CONSTANT_EXPRESSION,
    IS_PURE_FUNCTION,
    HAS_SIDE_EFFECTS,
    IS_RECURSIVE,
    CAN_BE_MEMOIZED,
    IS_DEAD_CODE,
    NEEDS_TYPE_CONVERSION
};

// 节点元数据信息
struct NodeMetadata {
    std::string node_type;
    size_t unique_id;
    int depth;
    std::optional<size_t> parent_id;
    SourcePosition position;
    size_t child_count;
    size_t memory_size;
    std::set<AnalysisFlag> analysis_flags;
    std::unordered_map<std::string, std::string> attributes;
    
    NodeMetadata() : unique_id(0), depth(0), child_count(0), memory_size(0) {}
};

// 分析结果详情
struct AnalysisResult {
    std::optional<std::string> expression_type;
    std::string scope_info;
    std::set<std::string> side_effects;
    int complexity_score;
    std::vector<std::string> optimization_hints;
    std::unordered_map<std::string, std::string> symbol_references;
    
    AnalysisResult() : complexity_score(0) {}
};

// 输出配置选项
struct DetailedOutputConfig {
    bool show_types = true;
    bool show_positions = true;
    bool show_memory = true;
    bool show_analysis = true;
    bool show_optimization_hints = true;
    bool show_symbol_references = true;
    int max_depth = -1; // -1表示无限制
    
    enum class DetailLevel {
        BASIC,    // 基础信息
        STANDARD, // 标准详细信息
        VERBOSE,  // 详细信息
        FULL      // 全部信息
    };
    
    DetailLevel detail_level = DetailLevel::FULL;
};

// 元数据收集器
class MetadataCollector {
private:
    std::unordered_map<size_t, NodeMetadata> node_registry;
    std::unordered_map<size_t, AnalysisResult> analysis_cache;
    size_t next_id;
    std::string source_code;
    
public:
    MetadataCollector() : next_id(1) {}
    
    void set_source_code(const std::string& source) { source_code = source; }
    
    size_t register_node(const std::string& node_type, int depth, size_t parent_id = 0);
    void set_node_position(size_t node_id, const SourcePosition& pos);
    void add_node_attribute(size_t node_id, const std::string& key, const std::string& value);
    void set_analysis_flag(size_t node_id, AnalysisFlag flag);
    void set_analysis_result(size_t node_id, const AnalysisResult& result);
    
    const NodeMetadata* get_node_metadata(size_t node_id) const;
    const AnalysisResult* get_analysis_result(size_t node_id) const;
    
    // 分析方法
    void analyze_expression_type(size_t node_id, ASTNode* node);
    void analyze_scope_info(size_t node_id, ASTNode* node);
    void analyze_complexity(size_t node_id, ASTNode* node);
    void analyze_memory_usage(size_t node_id, ASTNode* node);
};

// AST详细输出器
class ASTDetailedPrinter : public ASTVisitor {
private:
    std::ostringstream output;
    DetailedOutputConfig config;
    MetadataCollector metadata_collector;
    int current_depth;
    size_t current_parent_id;
    
    // 输出格式化方法
    void print_section_header(const std::string& title);
    void print_section_footer();
    void print_node_header(const NodeMetadata& metadata);
    void print_node_footer();
    void print_metadata_section(const NodeMetadata& metadata);
    void print_analysis_section(size_t node_id);
    void print_children_header();
    void print_children_footer();
    
    // 辅助方法
    std::string format_analysis_flags(const std::set<AnalysisFlag>& flags);
    std::string format_memory_size(size_t bytes);
    std::string format_complexity_score(int score);
    bool should_show_node(const NodeMetadata& metadata);
    
    // 访问节点并收集元数据
    size_t visit_with_metadata(ASTNode* node, const std::string& node_type);
    
    // 打印节点信息（在添加属性后调用）
    void print_node_info(size_t node_id);
    
public:
    explicit ASTDetailedPrinter(const DetailedOutputConfig& cfg = DetailedOutputConfig());
    
    void set_source_code(const std::string& source) {
        metadata_collector.set_source_code(source);
    }
    
    std::string get_detailed_output() const { return output.str(); }
    
    // ASTVisitor接口实现
    void visit(NumberLiteral& node) override;
    void visit(StringLiteral& node) override;
    void visit(Identifier& node) override;
    void visit(SpecialConstantNode& node) override;
    void visit(BinaryExpression& node) override;
    void visit(UnaryExpression& node) override;
    void visit(CallExpression& node) override;
    void visit(ListLiteral& node) override;
    void visit(DictLiteral& node) override;
    void visit(IndexExpression& node) override;
    void visit(LetStatement& node) override;
    void visit(EchoStatement& node) override;
    void visit(IfStatement& node) override;
    void visit(WhileStatement& node) override;
    void visit(ForStatement& node) override;
    void visit(FunctionStatement& node) override;
    void visit(ReturnStatement& node) override;
    void visit(CallStatement& node) override;
    void visit(Program& node) override;
};

} // namespace viml